package org.example.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.MonthDaySerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.ZonedDateTimeSerializer;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;

public class JacksonSettingSingleton {
    // 饿汉式单例，在类加载时就创建实例
    private static final ObjectMapper INSTANCE;

    static {
        INSTANCE = new ObjectMapper();
        // 注册 JavaTimeModule 以支持 Java 8 日期时间类型
        JavaTimeModule module = new JavaTimeModule();
        DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 配置 LocalDateTime 序列化
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(localDateTimeFormatter));

        // 配置 Date 格式
        INSTANCE.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        // 配置 ZonedDateTime 序列化（使用时区信息）
        module.addSerializer(ZonedDateTime.class, new ZonedDateTimeSerializer(localDateTimeFormatter.withZone(ZoneId.systemDefault())));

        // 配置 OffsetDateTime：自定义序列化器
        module.addSerializer(OffsetDateTime.class, new JsonSerializer<>() {
            @Override
            public void serialize(OffsetDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {
                gen.writeString(localDateTimeFormatter.format(value.toLocalDateTime()));
            }
        });

        // 配置 Instant：转换为系统默认时区后序列化
        module.addSerializer(Instant.class, new JsonSerializer<Instant>() {
            @Override
            public void serialize(Instant value, JsonGenerator gen, SerializerProvider provider) throws IOException {
                gen.writeString(localDateTimeFormatter.format(value.atZone(ZoneId.systemDefault())));
            }
        });

        // 配置 MonthDay 格式
        DateTimeFormatter monthDayFormatter = DateTimeFormatter.ofPattern("MM-dd");
        module.addSerializer(MonthDay.class, new MonthDaySerializer(monthDayFormatter));

        INSTANCE.registerModule(module);
        INSTANCE.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        INSTANCE.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
    }

    public static ObjectMapper getInstance() {
        return INSTANCE;
    }

    public static ObjectMapper getObjectMapper() {
        return INSTANCE;
    }

    private JacksonSettingSingleton() {
    }
}
